<script setup lang="ts">
import {
  type EventType,
  type ButtonProps,
  type DialogOptions,
  closeDialog,
  dialogStore
} from "./index";
import { ref, computed } from "vue";
import { isFunction } from "@pureadmin/utils";
import Fullscreen from "@iconify-icons/ri/fullscreen-fill";
import ExitFullscreen from "@iconify-icons/ri/fullscreen-exit-fill";

defineOptions({
  name: "ReDialog"
});

const fullscreen = ref(false);

const footerButtons = computed(() => {
  return (options: DialogOptions) => {
    return options?.footerButtons?.length > 0
      ? options.footerButtons
      : ([
        {
          label: "取消",
          bg: true,
          btnClick: ({ dialog: { options, index } }) => {
            const done = () =>
              closeDialog(options, index, { command: "cancel" });
            if (options?.beforeCancel && isFunction(options?.beforeCancel)) {
              options.beforeCancel(done, { options, index });
            } else {
              done();
            }
          }
        },
        {
          label: "确定",
          type: "primary",

          bg: true,
          popconfirm: options?.popconfirm,
          btnClick: ({ dialog: { options, index } }) => {
            const done = () =>
              closeDialog(options, index, { command: "sure" });
            if (options?.beforeSure && isFunction(options?.beforeSure)) {
              options.beforeSure(done, { options, index });
            } else {
              done();
            }
          }
        }
      ] as Array<ButtonProps>);
  };
});

const fullscreenClass = computed(() => {
  return [
    "el-icon",
    "el-dialog__close",
    "-translate-x-2",
    "cursor-pointer",
    "hover:!text-[red]"
  ];
});

function eventsCallBack(
  event: EventType,
  options: DialogOptions,
  index: number,
  isClickFullScreen = false
) {
  if (!isClickFullScreen) fullscreen.value = options?.fullscreen ?? false;
  if (options?.[event] && isFunction(options?.[event])) {
    return options?.[event]({ options, index });
  }
}

function handleClose(
  options: DialogOptions,
  index: number,
  args = { command: "close" }
) {
  closeDialog(options, index, args);
  eventsCallBack("close", options, index);
}
</script>

<template>
  <el-dialog v-for="(options, index) in dialogStore" :key="index" v-bind="options" v-model="options.visible"
    class="pure-dialog" :fullscreen="fullscreen ? true : options?.fullscreen ? true : false"
    @closed="handleClose(options, index)" @opened="eventsCallBack('open', options, index)"
    @openAutoFocus="eventsCallBack('openAutoFocus', options, index)"
    @closeAutoFocus="eventsCallBack('closeAutoFocus', options, index)">
    <!-- header -->
    <template v-if="options?.fullscreenIcon || options?.headerRenderer" #header="{ close, titleId, titleClass }">
      <div v-if="options?.fullscreenIcon" class="flex items-center justify-between">
        <span :id="titleId" :class="titleClass">{{ options?.title }}</span>
        <i v-if="!options?.fullscreen" :class="fullscreenClass" @click="() => {
          fullscreen = !fullscreen;
          eventsCallBack(
            'fullscreenCallBack',
            { ...options, fullscreen },
            index,
            true
          );
        }
          ">
          <IconifyIconOffline class="pure-dialog-svg" :icon="options?.fullscreen
            ? ExitFullscreen
            : fullscreen
              ? ExitFullscreen
              : Fullscreen
            " />
        </i>
      </div>
      <component :is="options?.headerRenderer({ close, titleId, titleClass })" v-else />
    </template>
    <component v-bind="options?.props" :is="options.contentRenderer({ options, index })"
      @close="args => handleClose(options, index, args)" />
    <!-- footer -->
    <template v-if="!options?.hideFooter" #footer>
      <template v-if="options?.footerRenderer">
        <component :is="options?.footerRenderer({ options, index })" />
      </template>
      <span v-else>
        <template v-for="(btn, key) in footerButtons(options)" :key="key">
          <el-popconfirm v-if="btn.popconfirm" v-bind="btn.popconfirm" @confirm="
            btn.btnClick({
              dialog: { options, index },
              button: { btn, index: key }
            })
            ">
            <template #reference>
              <el-button v-bind="btn">{{ btn?.label }}</el-button>
            </template>
          </el-popconfirm>
          <el-button v-else v-bind="btn" @click="
            btn.btnClick({
              dialog: { options, index },
              button: { btn, index: key }
            })
            ">
            {{ btn?.label }}
          </el-button>
        </template>
      </span>
    </template>
  </el-dialog>
</template>
